package com.itxixi.domain.strategy.service.rule.factory;


import com.itxixi.domain.strategy.model.entity.RuleActionEntity;
import com.itxixi.domain.strategy.service.annotation.LogicStrategy;
import com.itxixi.domain.strategy.service.rule.ILogicFilter;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Fuzhengwei bugstack.cn @小傅哥
 * @description 规则工厂  帮组我们更好的使用ILogicFilter
 * @create 2023-12-31 11:23
 */
@Service
public class DefaultLogicFactory {

    //成员变量  注册到对应的logicFilterMap 中
            //<rule_weight,RuleWeightLogicFilter (implements ILogicFilter<RuleActionEntity.RaffleBeforeEntity>)>
    public Map<String, ILogicFilter<?>> logicFilterMap = new ConcurrentHashMap<>();//抽象工厂

    // !!!!!!当 Spring创建 DefaultlogicFactory 实例时，它会自动将 Spring 容器中所有实现了 ILogicFilter 接口的Bean 作为参数传入构造函数 logicFilters 。
           //一组规则过滤器 每个过滤器有LogicStrategy注解 而注解含有的方法就是本类中的枚举类实例 最后得到Map
    public DefaultLogicFactory(List<ILogicFilter<?>> logicFilters) {//构造方法
        logicFilters.forEach(logic -> {  //找到每个logic过滤器类上标注的LogicStrategy注解。
            LogicStrategy strategy = AnnotationUtils.findAnnotation(logic.getClass(), LogicStrategy.class);
            //@LogicStrategy(logicMode = DefaultLogicFactory.LogicModel.RULE_BLACKLIST) 注解用的就是本类的枚举类
            if (null != strategy) {
                logicFilterMap.put(strategy.logicMode().getCode(), logic);
                                //("rule_weight", RuleWeightLogicFilter )
                                //("rule_blacklist",RuleBackListLogicFilter)
            }
        });
    }
    //RuleActionEntity ：code info ruleModel data(strategyId awardId ruleWeightValueKey）
          //泛型方法 <T extends RuleActionEntity.RaffleEntity> 就是为了修饰ILogicFilter<T>里的T
    public <T extends RuleActionEntity.RaffleEntity> Map<String, ILogicFilter<T>> openLogicFilter() {
        return (Map<String, ILogicFilter<T>>) (Map<?, ?>) logicFilterMap;//两次强制转换
        //1消除编译器对类型不匹配的警告 Map<String, ILogicFilter<?>> 无法编译成 Map<String, ILogicFilter<T>> 会被编译器认为不兼容
        //所以return (Map<String, ILogicFilter<T>>) logicFilterMap;是错的 所以需要先(Map<?, ?>)
                                                                         //2明确类型
    }
    //Map<String, ILogicFilter<RaffleBeforeEntity>> beforeFilterMap = logicFactory.openLogicFilter();

    @Getter
    @AllArgsConstructor
    public enum LogicModel {

        RULE_WIGHT("rule_weight","【抽奖前规则】根据抽奖权重返回可抽奖范围KEY"),
        RULE_BLACKLIST("rule_blacklist","【抽奖前规则】黑名单规则过滤，命中黑名单则直接返回"),

        ;

        private final String code;
        private final String info;

    }

}
